#include "myHttpServer.hpp"
static const string SEP = "\r\n";
static const string default_catalog = "index.html";
//static const string path = "./test.html";
// GET /favicon.ico HTTP/1.1
// Host: 121.4.111.111:8080
// Connection: keep-alive
// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81
// Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
// Referer: http://121.4.111.111:8080/
// Accept-Encoding: gzip, deflate
// Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
void ReadFile(const string &path, string &body)
{
    struct stat st;
    int n = stat(path.c_str(), &st);
    int size = st.st_size;
    body.resize(size);
    int fd = open(path.c_str(), O_RDONLY);
    if (fd < 0)
    {
        return;
    }
    int s = read(fd, (char *)body.c_str(), size);
    close(fd);
    logMessge(INFO, "读取文件！");
}
void ParseLine(const string &line, string &method_, string &url_, string &version_)
{
    std::stringstream ss(line);
    ss >> method_ >> url_ >> version_;
}
string ReadOneLine(string &str, const string &sep)
{
    int pos = str.find(sep);
    if (pos == string::npos)
    {
        return string("");
    }
    string line = str.substr(0, pos);
    str.erase(0, pos + sep.size());
    return line;
}
class Request
{
public:
    Request() {}
    ~Request() {}
    void Deserialize(string &message, const string &sep)
    {
        string line = ReadOneLine(message, SEP);  // 拿到了一行
        logMessge(DEBUG,"拿到首行信息");
        ParseLine(line, method_, url_, version_); // 拿到首行信息
        while (!message.empty())
        {
            line = ReadOneLine(message, sep);
            body_.push_back(line);
        }
        if(url_.c_str()[url_.size()-1]=='/')
            url_+=default_catalog;
        path_ += "wwwroot"+url_;
        int pos = path_.rfind(".");
        if (pos == string::npos)
            suffix_ = ".html";
        else 
            suffix_ = path_.substr(pos);
    }
    void Print()
    {
        cout << "method_: " << method_ << endl
             << "url_: " << url_ << endl
             << "version_: " << version_ << endl;
    }

public:
    string method_;
    string url_;
    string version_;
    vector<string> body_;
    string suffix_;
    string path_;
};
string GetContentType(const std::string &suffix)
{
    std::string content_type = "Content-Type: ";
    if (suffix == ".html" || suffix == ".htm")
        content_type + "text/html";
    else if (suffix == ".css")
        content_type += "text/css";
    else if (suffix == ".js")
        content_type += "application/x-javascript";
    else if (suffix == ".png")
        content_type += "image/png";
    else if (suffix == ".jpg")
        content_type += "image/jpeg";
    else
    {
    }
    return content_type + SEP;
}
string excuteFunc(string &message)
{
    cout << "--------------------------------------------" << endl;
    cout << message << endl;
    Request rsq;
    rsq.Deserialize(message, SEP); // 反序列化;
    rsq.Print();                   // 打印首行信息
    string body;
    // 序列化响应
    ReadFile(rsq.path_,body);
    string resp = "HTTP/1.1 200 ok" + SEP;
    resp += "Content-Length: " + to_string(body.size()) + SEP;
    resp += "Content-Type: " + GetContentType(rsq.suffix_) ;
    resp += SEP;
    resp += body;
    resp+=SEP;
    logMessge(DEBUG,"resp:%s",resp.c_str());
    return resp;
}
int main(int arc, char *args[])
{
    uint16_t port = atoi(args[1]);

    unique_ptr<httpserver> tsvr(new httpserver(excuteFunc, port));
    tsvr->Init();
    tsvr->Start();

    return 0;
}